package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.AddRoleDto;
import com.zzyl.dto.RolePageQueryDto;
import com.zzyl.dto.UpdateRoleDto;
import com.zzyl.entity.Resource;
import com.zzyl.entity.Role;
import com.zzyl.entity.RoleResource;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.RoleResourceMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.zzyl.constant.SuperConstant.DATA_STATE_0;

@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public PageResponse<Role> page(Integer pageNum, Integer pageSize, RolePageQueryDto dto) {
        PageHelper.startPage(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        Page<Role> page = roleMapper.pageQuery(dto);
        return PageResponse.of(page, Role.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AddRoleDto dto) {
        Role roleDB = roleMapper.selectByName(dto.getRoleName());
        if (roleDB != null) {
            throw new BaseException(BasicEnum.DATA_EXIST);
        }
        // 保存
        Role role = BeanUtil.copyProperties(dto, Role.class);
        role.setSortNo(1);
        roleMapper.insertSelective(role);
    }

    @Override
    public List<String> findCheckedResources(Long roleId) {
        return roleResourceMapper.findCheckedResources(roleId);
    }

    @Override
    public void update(UpdateRoleDto dto) {
        // 判断重复
        Role roleDB = roleMapper.selectByName(dto.getRoleName());
        if (roleDB == null) {
            // ok
        } else {
            if (Objects.equals(roleDB.getId(), dto.getId())) {
                //ok
            } else {
                throw new BaseException(BasicEnum.DATA_EXIST);
            }
        }
        //启用禁用
        roleDB = roleMapper.selectByPrimaryKey(dto.getId());
        if (roleDB == null) {
            throw new BaseException(BasicEnum.DATA_NOT_EXIST);
        }
        // 说明有修改状态
        if (!Objects.equals(roleDB.getDataState(), dto.getDataState())) {
            // 如果是禁用，判断是否关联到了用户
            if (Objects.equals(dto.getDataState(), SuperConstant.DATA_STATE_1)) {
                List<UserRole> userRoles = userRoleMapper.selectByRoleId(dto.getId());
                if (!CollectionUtils.isEmpty(userRoles)) {
                    throw new BaseException(BasicEnum.USER_ROLE_RELATED);
                }
            }
        }
        // 保存 role
        Role role = BeanUtil.copyProperties(dto, Role.class);
        roleMapper.updateByPrimaryKeySelective(role);
        // 没操作资源
        if (dto.getCheckedResourceNos() == null) {
            return;
        }
        // 删除关联关系
        roleResourceMapper.deleteByRoleId(dto.getId());
        // 插入新的关联关系
        if (!CollectionUtils.isEmpty(dto.getCheckedResourceNos())) {
            List<RoleResource> roleResources = dto.getCheckedResourceNos().stream().map(resourceNo -> {
                RoleResource rr = new RoleResource();
                rr.setRoleId(dto.getId());
                rr.setResourceNo(resourceNo);
                rr.setDataState(DATA_STATE_0);
                return rr;
            }).collect(Collectors.toList());
            roleResourceMapper.batchInsert(roleResources);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRoleById(Long roleId) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        if(role == null){
            throw new BaseException(BasicEnum.DATA_NOT_EXIST);
        }
        // 判断状态，如果是启用 禁止删除
        if(Objects.equals(role.getDataState(), DATA_STATE_0)){
            throw new BaseException(BasicEnum.CANNOT_DELETE_ROLE_ENBABLE);
        }
        // 删除角色与菜单关联
        roleResourceMapper.deleteByRoleId(roleId);
        roleMapper.deleteByPrimaryKey(roleId);
    }
    @Override
    public List<Role> list() {
        return roleMapper.selectRoleByStatus(DATA_STATE_0);
    }
}
